package org.zjt.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * @author juntao.zhang
 * @version V1.0
 * @Description: beforeExecute 、afterExecute 做一些线程上下文的 threadlocal 设置
 * @Package org.zjt.thread
 * @date 2018/6/17 18:13
 * @see ThreadPoolExecutor
 *
 * default : 必须在同一个包中，才可以引用、覆盖、继承
 */
@Slf4j
public class ThreadPoolExecutorTest {

    public static void main(String[] args) {
        MyThreadPoolExecutor poolExecutor = new MyThreadPoolExecutor(2,4,20, TimeUnit.SECONDS,new PriorityBlockingQueue<>());
        poolExecutor.execute(() -> log.info("running"));
        BlockingQueue<Runnable> queue = poolExecutor.getQueue();
        log.info("queue size:{}",queue.size());
        log.info("TaskCount:{} \t ActiveCount:{} \t CompletedTaskCount:{}",poolExecutor.getTaskCount(),poolExecutor.getActiveCount(),poolExecutor.getCompletedTaskCount());
        poolExecutor.shutdown();


    }
}

@Slf4j
class MyThreadPoolExecutor extends ThreadPoolExecutor{

    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    }

    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
    }

    public MyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    /**
     * 例如，重新初始化 ThreadLocals，收集统计信息或添加日志条目。
       *此外，可以覆盖方法{@link #terminated}来执行
       *执行程序执行后需要执行的任何特殊处理
       *完全终止。
     * @param t
     * @param r
     */
    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        log.info("-------------------beforeExecute set Thread Local-------------------------");
    }

    /**
     * 回调删除threadlocal 、 处理异常
     * @param r
     * @param t
     */
    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        log.info("-------------------afterExecute delete ThreadLocal and handle exception-------------------------");
    }

    /**
     *  允许访问工作队列用于监视和调试。
     * @return
     */
    @Override
    public BlockingQueue<Runnable> getQueue() {
        return super.getQueue();
    }

    /**
     * 关闭资源
     */
    @Override
    protected void terminated() {
        log.info("-------------------terminal executors and close resource-------------------------");
    }

    /**
     * 默认实现： executor 被GC时候，会被自动shutdown 。但不建议这么写。导致OOM。减缓被删除。
     */
    @Override
    protected void finalize() {
        shutdown();
    }


}